#pragma once
#include "Socket.hpp"
#include "Epoll.hpp"
#include "Connection.hpp"
#include "Response.hpp"
class HttpServer
{
public:
    using HttpServerPtr = shared_ptr<HttpServer>;

public:
    HttpServer(int port) : _port(port), _isrunning(false)
    {
        _socket = make_shared<Socket_tcp>(port); // 创建套接字
        Init();
        int opt = 1;
        int n = setsockopt(_socketfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); // 设置套接字选项
        if (n < 0)
        {
            exit(-1);
        }
    }

    void Init()
    {
        _socket->Create();
        _epoll.Init();
        _socketfd = _socket->Socket_fd(); // 获取套接字的文件描述符

        shared_ptr<Connection> conn = make_shared<Connection>(_socketfd);

        conn->Set_read_callback([this]()
                                {
            int newfd=this->_socket->Accept();
            if(newfd<=0) return;

            shared_ptr<Connection> newconn=make_shared<Connection>(newfd);
            newconn->Set_read_callback([newconn,this](){
                char buffer[1024*8]{0};
                cout<<"new conn fd:"<<newconn->Fd()<<endl;
                int n=recv(newconn->Fd(),buffer, sizeof(buffer)-1,0);
                if (n < 0)
                {
                    cout<<"recv error"<<endl;
                    perror("recv:");
                }
                else if (n == 0)
                {
                    cout<<"client close"<<endl;
                    _epoll.Removeepoll(newconn->Fd());
                    _connections.erase(newconn->Fd());
                }
                
                buffer[n] = 0;
                cout<<"get data from client: "<<buffer<<endl;
                string response_data;

                string request_data=buffer;
                HttpRequestParser request(request_data);
                Response response(request);
                

                response.Getindex_html(response_data);
                // LOG(LogLevel::INFO)<<"send data to client: "<<response_data;

                // std::string status_line = "HTTP/1.1 200 OK" + space + line_break;
                // // 直接返回一个html网页
                // std::string body = "<!DOCTYPE html>\
                //             <html>\
                //            <head>\
                //            <meta charset = \"UTF-8\">\
                //            <title> 钟哥是帅b</title>\
                //            </head>\
                //            <body>\
                //            <p> 点击瞎下载</ p>\
                //            <a class=\"min\"  href=\"https://ys.mihoyo.com//\" target=\"_blank\">免费下载黄片</a>\
                //            </body> </html>";
                // response_data=status_line+body;


                // cout<<"send data to client: "<<response_data<<endl;
                 n=send(newconn->Fd(),response_data.c_str(),response_data.size(),0);
                if(n<0)
                {
                    perror("send:");
                }
                else 
                {
                    cout<<"send data to client success"<<endl;
                }
                close(newconn->Fd());
                _epoll.Removeepoll(newconn->Fd());
                _connections.erase(newconn->Fd());
            });
            _epoll.Setepoll(EPOLLIN,newconn->Fd());
            _connections[newconn->Fd()]=newconn; });

        epoll_event event;
        event.events = EPOLLIN;
        event.data.fd = _socketfd;
        _epoll.Setepoll(event.events, event.data.fd);
        _connections[_socketfd] = conn;
    }

    void Start()
    {
        LOG(LogLevel::INFO) << "HttpServer start...";
        _isrunning = true;
        // while (_isrunning)
        // {
        //     _socket->Accept();
        //     string getdata;
        //     _socket->Recev(getdata);
        //     LOG(LogLevel::INFO)<<"get data from client: "<<getdata;
        // }

        _epoll.Loop(_connections);
    }

private:
    int _socketfd;
    shared_ptr<Socket> _socket;
    bool _isrunning;
    int _port;

    Epoll _epoll;
    unordered_map<int, shared_ptr<Connection>> _connections;
};
